<template>
  <div class="deploy-create p-4">
    <el-card class="box-card">
      <template #header>
        <div class="card-header flex items-center justify-between">
          <h2 class="text-xl font-bold">创建部署</h2>
        </div>
      </template>

      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="max-w-4xl">
        <!-- 项目选择 -->
        <el-form-item label="选择项目" prop="projectId">
          <el-select 
            v-model="form.projectId" 
            filterable 
            placeholder="请选择项目" 
            class="w-full"
            @change="handleProjectChange"
          >
            <el-option 
              v-for="item in projectOptions" 
              :key="item.id" 
              :label="item.name" 
              :value="item.id"
            >
              <div class="flex items-center">
                <span>{{ item.name }}</span>
                <el-tag class="ml-2" size="small" :type="item.type === ProjectType.FRONTEND ? 'success' : 'info'">
                  {{ item.type === ProjectType.FRONTEND ? '前端' : '后端' }}
                </el-tag>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <!-- 选择环境 -->
        <el-form-item label="部署环境" prop="environment">
          <el-select 
            v-model="form.environment" 
            placeholder="请选择部署环境" 
            class="w-full"
            @change="handleEnvironmentChange"
          >
            <el-option label="开发环境" :value="DeployEnvironment.DEVELOPMENT" />
            <el-option label="测试环境" :value="DeployEnvironment.TESTING" />
            <el-option label="生产环境" :value="DeployEnvironment.PRODUCTION" />
          </el-select>
        </el-form-item>

        <!-- 部署路径 -->
        <el-form-item label="部署路径" prop="deploy_path">
          <el-input 
            v-model="form.deploy_path" 
            placeholder="请输入部署路径，留空则使用默认路径" 
            class="w-full"
          />
        </el-form-item>
        
        <!-- 选择服务器 -->
        <el-form-item label="选择服务器" prop="serverIds">
          <el-select 
            v-model="form.serverIds" 
            multiple 
            collapse-tags 
            :loading="serverLoading"
            placeholder="请选择服务器" 
            class="w-full"
          >
            <el-option 
              v-for="server in filteredServerList" 
              :key="server.id" 
              :label="`${server.hostname} (${server.ip})${server.notes ? ' - ' + server.notes : ''}`" 
              :value="Number(server.id)"
            >
              <div class="flex items-center">
                <span>{{ server.hostname }}</span>
                <span class="text-gray-400 ml-2">({{ server.ip }})</span>
                <el-tag class="ml-2" size="small" :type="server.server_status === ServerStatus.ONLINE ? 'success' : 'danger'">
                  {{ server.server_status === ServerStatus.ONLINE ? '在线' : '离线' }}
                </el-tag>
              </div>
            </el-option>
          </el-select>
          <div class="text-xs text-gray-400 mt-1">
            当前环境可用服务器: {{ filteredServerList.length }} 台
          </div>
        </el-form-item>

        <!-- 版本号 -->
        <el-form-item label="版本号" prop="version">
          <el-select
            v-model="form.version"
            placeholder="请选择版本号"
            :loading="versionsLoading"
            class="w-full"
            filterable
            allow-create
            :disabled="!form.projectId"
          >
            <el-option
              v-for="item in packageVersions"
              :key="item.filename"
              :label="item.filename"
              :value="item.filename"
            >
              <div class="flex items-center justify-between w-full">
                <span>{{ item.filename }}</span>
                <span class="text-gray-400 text-xs" v-if="item.version">{{ item.version }}</span>
                <el-tag v-if="item.is_current" size="small" type="success" class="ml-2">当前版本</el-tag>
              </div>
            </el-option>
          </el-select>
          <!-- 如果没有选择项目 -->
          <div v-if="!form.projectId" class="text-xs text-gray-400 mt-1">
            请先选择项目
          </div>
          <!-- 如果没有找到版本，提示用户可以手动输入 -->
          <div v-else-if="packageVersions.length === 0" class="text-xs text-gray-400 mt-1">
            此项目未找到版本，请手动输入版本号
          </div>
          <!-- 如果有版本 -->
          <div v-else class="text-xs text-gray-400 mt-1">
            已加载 {{ packageVersions.length }} 个可用版本
          </div>
        </el-form-item>

        <!-- 项目信息展示 -->
        <div v-if="selectedProject" class="bg-gray-50 p-4 rounded-md mb-6">
          <h3 class="text-lg font-semibold mb-4">已选择项目信息</h3>
          
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <div class="text-gray-500 text-sm mb-1">项目名称</div>
              <div>{{ selectedProject.name }}</div>
            </div>
            
            <div>
              <div class="text-gray-500 text-sm mb-1">项目类型</div>
              <div>
                <el-tag :type="selectedProject.type === ProjectType.FRONTEND ? 'success' : 'info'">
                  {{ selectedProject.type === ProjectType.FRONTEND ? '前端' : '后端' }}
                </el-tag>
              </div>
            </div>
            
            <div>
              <div class="text-gray-500 text-sm mb-1">项目描述</div>
              <div>{{ selectedProject.description || '无' }}</div>
            </div>
            
            <div>
              <div class="text-gray-500 text-sm mb-1">项目状态</div>
              <div>
                <el-tag :type="getStatusTag(selectedProject.status)">
                  {{ getStatusName(selectedProject.status) }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>

        <!-- 部署步骤预览 -->
        <div v-if="selectedProject" class="mb-6">
          <h3 class="text-lg font-semibold mb-4">部署步骤</h3>
          
          <el-timeline>
            <el-timeline-item 
              v-for="(step, index) in deploySteps" 
              :key="step.name"
              :type="getStepType(step.status)"
              :color="getStepColor(step.status)"
            >
              <h4>{{ index + 1 }}. {{ step.title }}</h4>
              <p class="text-gray-500 text-sm">{{ step.desc }}</p>
            </el-timeline-item>
          </el-timeline>
        </div>

        <!-- 提交按钮 -->
        <el-form-item>
          <el-button type="primary" @click="submitForm(formRef)">开始部署</el-button>
          <el-button @click="resetForm(formRef)">重置</el-button>
          <el-button @click="goBack">取消</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElNotification } from 'element-plus'
import { getServerList } from '@/request/server-api'
import { getPackageVersions, PackageResponse, PackageInfo } from '@/request/package-api'
import { getProjectList, getProject } from '@/request/project-api'
import { createDeployment, scanDirectoryFiles } from '@/request/deploy-api'
import { ProjectType, ProjectStatus } from '@/model/project-model'
import { DeployEnvironment, DeployStep, DeployStatus } from '@/model/deploy-model'
import { ServerEnvironment, ServerStatus } from '@/model/server-model'
import type { Server } from '@/model/server-model'
import type { Project } from '@/model/project-model'

defineOptions({
  name: 'DeployCreate'
})

const router = useRouter()
const formRef = ref<FormInstance>()
const projectOptions = ref<Project[]>([])
const loading = ref(false)
const selectedProject = ref<Project | null>(null)

// 服务器列表
const serverList = ref<Server[]>([])
const serverLoading = ref(false)

// 包版本列表
interface VersionOption {
  filename: string;
  version: string;
  id: number;
  is_current: boolean;
  path: string;
}

const packageVersions = ref<VersionOption[]>([])
const versionsLoading = ref(false)

// 部署环境到服务器环境的映射
const mapDeployToServerEnv = (deployEnv: DeployEnvironment): ServerEnvironment => {
  switch (deployEnv) {
    case DeployEnvironment.DEVELOPMENT:
      return ServerEnvironment.DEVELOPMENT
    case DeployEnvironment.TESTING:
      return ServerEnvironment.TESTING
    case DeployEnvironment.PRODUCTION:
      return ServerEnvironment.PRODUCTION
    default:
      return ServerEnvironment.DEVELOPMENT
  }
}

const filteredServerList = computed(() => {
  // 根据选择的环境过滤服务器列表
  const mappedEnv = mapDeployToServerEnv(form.environment)
  // 增加日志查看服务器列表状态
  console.log('服务器状态类型:', serverList.value.map(s => s.server_status))
  
  return serverList.value.filter(server => {
    // 包含 ACTIVE 和 ONLINE 状态
    const validStatus = server.server_status === ServerStatus.ONLINE || server.server_status === ServerStatus.ACTIVE
    return server.environment === mappedEnv && validStatus
  })
})

// 表单数据
const form = reactive({
  projectId: '',
  environment: DeployEnvironment.DEVELOPMENT,
  version: '',
  serverIds: [] as number[],
  project_version_id: 0,
  deploy_path: '',
  deployed_by: ''
})

// 表单验证规则
const rules = reactive<FormRules>({
  projectId: [
    { required: true, message: '请选择项目', trigger: 'change' }
  ],
  environment: [
    { required: true, message: '请选择部署环境', trigger: 'change' }
  ],
  serverIds: [
    { required: true, message: '请选择至少一台服务器', trigger: 'change' },
    { type: 'array', min: 1, message: '请至少选择一台服务器', trigger: 'change' }
  ],
  version: [
    { required: true, message: '请输入版本号', trigger: 'blur' },
    { 
      // 允许完整的文件名格式，只检查其中包含有效的版本号部分
      validator: (rule, value, callback) => {
        // 检查文件名中是否包含有效的版本号格式 x.y.z
        if (!value || /\d+\.\d+\.\d+/.test(value)) {
          callback()
        } else {
          callback(new Error('文件名中需包含有效的版本号格式 x.y.z'))
        }
      },
      trigger: 'blur'
    }
  ]
})

// 获取部署步骤
const deploySteps = computed(() => {
  if (!selectedProject.value) return []
  
  const isFrontend = selectedProject.value.type === ProjectType.FRONTEND
  const steps = [
    {
      name: DeployStep.UPLOAD,
      title: '上传项目包',
      desc: '上传项目包到服务器',
      status: 'pending'
    },
    {
      name: DeployStep.EXTRACT,
      title: '解压项目包',
      desc: '解压项目包到指定目录',
      status: 'pending'
    },
    {
      name: DeployStep.COPY_CONFIG,
      title: '拷贝配置文件',
      desc: '拷贝配置文件到项目目录',
      status: 'pending'
    }
  ]
  
  // 前端项目需要额外的NPM操作
  if (isFrontend) {
    steps.push(
      {
        name: DeployStep.NPM_INSTALL,
        title: 'NPM 安装依赖',
        desc: '安装项目依赖',
        status: 'pending'
      },
      {
        name: DeployStep.NPM_BUILD,
        title: 'NPM 构建项目',
        desc: '构建前端项目',
        status: 'pending'
      }
    )
  } else {
    // 后端项目需要重启服务
    steps.push({
      name: DeployStep.RESTART,
      title: '重启服务',
      desc: '重启后端服务',
      status: 'pending'
    })
  }
  
  steps.push({
    name: DeployStep.COMPLETE,
    title: '完成部署',
    desc: '部署流程完成',
    status: 'pending'
  })
  
  return steps
})

// 获取项目列表
const getProjects = async () => {
  loading.value = true
  try {
    const response = await getProjectList({
      page: 1,
      page_size: 100,
      project_status: ProjectStatus.ACTIVE
    })
    projectOptions.value = response.data || []
  } catch (error) {
    console.error('获取项目列表失败:', error)
    ElMessage.error('获取项目列表失败')
  } finally {
    loading.value = false
  }
}

/**
 * 处理项目选择变化
 * 当选择项目时触发，自动获取项目版本
 */
const handleProjectChange = async (projectId: string) => {
  console.log('项目选择变化，选中ID:', projectId)
  
  // 清空旧的版本数据
  packageVersions.value = []
  form.version = ''
  
  // 如果未选择项目，直接返回
  if (!projectId) {
    selectedProject.value = null
    return
  }
  
  // 设置加载状态
  versionsLoading.value = true
  
  // 获取完整的项目详情，包含版本信息
  try {
    ElMessage.info(`正在获取项目版本信息...`)
    const response = await getProject(Number(projectId))
    console.log('获取项目详情API响应:', response)
    
    if (response.code === 0 && response.data) {
      selectedProject.value = response.data
      console.log('获取到项目详情:', selectedProject.value)
      
      // 使用项目详情中的版本信息
      let versionOptionsFromProject: VersionOption[] = []
      
      if (selectedProject.value.versions && selectedProject.value.versions.length > 0) {
        // 将项目版本转换为前端可用的格式
        versionOptionsFromProject = selectedProject.value.versions.map(v => ({
          filename: v.version,
          version: v.version,
          id: v.id,
          is_current: v.is_current,
          path: '' // 保持与接口定义兼容
        }))
      }
      
      // 重要修改：调用 /api/v1/file-scan/scan/[projectId] 获取具体版本文件数据
      try {
        // 使用项目的名称或ID作为 directoryId
        // Project类型中没有key属性，所以直接使用name或id的字符串形式
        const projectKey = selectedProject.value.name || String(selectedProject.value.id)
        console.log(`调用scanDirectoryFiles获取版本详情，项目标识: ${projectKey}`)
        
        // 调用文件扫描接口
        const scanResponse = await scanDirectoryFiles(projectKey)
        console.log('获取项目版本文件详情:', scanResponse)
        
        if (scanResponse.code === 0 && scanResponse.data && scanResponse.data.files) {
          // 使用文件扫描接口返回的版本列表
          const filesFromScan = scanResponse.data.files
          console.log(`成功获取到 ${filesFromScan.length} 个版本文件`)
          
          // 将文件扫描结果转换为VersionOption格式
          const versionOptionsFromScan: VersionOption[] = filesFromScan.map(file => ({
            filename: file.file_name,
            version: file.version,
            id: 0, // 使用默认ID
            is_current: false, // 默认非当前版本
            path: file.file_path || ''
          }))
          
          // 合并或使用扫描到的版本信息
          packageVersions.value = versionOptionsFromScan
          
          // 如果有版本，自动选择首个
          if (versionOptionsFromScan.length > 0) {
            // 选择第一个版本
            form.version = versionOptionsFromScan[0].filename
            ElMessage.success(`已加载 ${versionOptionsFromScan.length} 个版本文件`)
          } else {
            ElMessage.warning('未找到可部署的版本文件')
            // 回退到项目中的版本信息
            packageVersions.value = versionOptionsFromProject
          }
        } else {
          console.warn('获取项目版本文件失败')
          // 使用项目详情中的版本信息作为备选
          packageVersions.value = versionOptionsFromProject
          
          if (versionOptionsFromProject.length > 0) {
            const currentVersion = versionOptionsFromProject.find(v => v.is_current === true)
            if (currentVersion) {
              form.version = currentVersion.version
              ElMessage.success(`已自动选择当前版本: ${currentVersion.version}`)
            } else {
              form.version = versionOptionsFromProject[0].version
              ElMessage.success(`已加载 ${versionOptionsFromProject.length} 个版本`)
            }
          } else {
            ElMessage.warning('未找到可部署的版本文件')
          }
        }
        
      } catch (scanError) {
        console.error('获取项目版本文件详情失败:', scanError)
        ElMessage.error('获取项目版本文件详情失败')
        
        // 回退到项目中的版本信息
        packageVersions.value = versionOptionsFromProject
      }
      
      // 如果仍然没有版本，显示警告
      if (packageVersions.value.length === 0) {
        console.warn('项目没有可用的版本')
        ElMessage.warning('该项目没有找到版本信息，您可以手动输入版本号')
      }
    } else {
      console.warn('获取项目详情失败')
      ElMessage.error(response.errorMsg || '获取项目详情失败')
      selectedProject.value = null
    }
  } catch (error) {
    console.error('获取项目详情失败:', error)
    ElMessage.error('获取项目详情失败')
    selectedProject.value = null
  } finally {
    versionsLoading.value = false
  }
  
  // 清空已选择的服务器
  form.serverIds = []
}

// 处理环境选择变化
const handleEnvironmentChange = () => {
  // 清空已选择的服务器
  form.serverIds = []
  
  // 重新获取对应环境的服务器列表
  fetchServerList()
}

// 获取服务器列表
const fetchServerList = async () => {
  const mappedEnv = mapDeployToServerEnv(form.environment)
  serverLoading.value = true
  try {
    const response = await getServerList({
      page: 1,
      page_size: 100,
      environment: mappedEnv
    })
    console.log('服务器列表API响应:', response)
    
    // 确保 serverList.value 始终是一个数组
    if (response.data && typeof response.data === 'object' && 'items' in response.data && Array.isArray((response.data as any).items)) {
      // 使用 items 作为服务器数组来源
      serverList.value = (response.data as any).items;
    } else if (Array.isArray(response.data)) {
      serverList.value = response.data;
    } else if (response.data && typeof response.data === 'object' && 'list' in response.data && Array.isArray((response.data as any).list)) {
      // 兼容可能的 {list: []} 格式
      serverList.value = (response.data as any).list;
    } else {
      serverList.value = [];
    }
    
    console.log('处理后的服务器列表:', serverList.value)
    console.log('过滤后的服务器列表:', filteredServerList.value)
  } catch (error) {
    console.error('获取服务器列表失败:', error)
    ElMessage.error('获取服务器列表失败')
    serverList.value = []
  } finally {
    serverLoading.value = false
  }
}

/**
 * 获取项目包版本列表 (替代或补充项目详情中的版本信息)
 */
const fetchPackageVersions = async () => {
  if (!selectedProject.value) {
    console.log('未选择项目，无法获取版本列表')
    return
  }
  
  console.log('获取项目版本列表，项目名称:', selectedProject.value.name)
  versionsLoading.value = true
  
  try {
    const response = await getPackageVersions(selectedProject.value.name)
    console.log('包版本API响应:', response)
    
    // 根据API文档，包版本列表在 response.data.packages 中
    if (response.data && response.data.packages) {
      // 转换为VersionOption类型
      const packages: PackageInfo[] = response.data.packages
      
      // 转换为需要的格式
      const versionOptions: VersionOption[] = packages.map(pkg => ({
        filename: pkg.filename,
        version: pkg.version || pkg.filename,  // 如果没有version属性，使用filename
        id: 0,  // 这里需要设置默认值
        is_current: false, // 默认为非当前版本
        path: pkg.path || ''
      }))
      
      packageVersions.value = versionOptions
      console.log('设置包版本列表:', packageVersions.value)
    } else {
      packageVersions.value = []
      console.warn('API返回的packages数组为空')
    }
    
    // 默认不选择任何版本
    if (packageVersions.value.length > 0 && !form.version) {
      form.version = packageVersions.value[0].filename
    } else {
      form.version = ''
    }
  } catch (error) {
    console.error('获取包版本列表失败:', error)
    ElMessage.error('获取包版本列表失败')
    form.version = generateVersion() // 失败时使用生成的版本
    packageVersions.value = []
  } finally {
    versionsLoading.value = false
  }
}

// 生成版本号
const generateVersion = () => {
  const date = new Date()
  const year = date.getFullYear().toString().substring(2) // 年份取后两位
  const month = (date.getMonth() + 1).toString().padStart(2, '0')
  const day = date.getDate().toString().padStart(2, '0')
  const hour = date.getHours().toString().padStart(2, '0')
  const minute = date.getMinutes().toString().padStart(2, '0')
  
  return `${year}.${month}${day}.${hour}${minute}`
}

// 获取步骤类型
const getStepType = (status: string) => {
  switch (status) {
    case 'success':
      return 'success'
    case 'processing':
      return 'primary'
    case 'failed':
      return 'danger'
    default:
      return 'info'
  }
}

// 获取步骤颜色
const getStepColor = (status: string) => {
  switch (status) {
    case 'success':
      return '#67C23A'
    case 'processing':
      return '#409EFF'
    case 'failed':
      return '#F56C6C'
    default:
      return '#909399'
  }
}

// 获取状态标签类型
const getStatusTag = (status: string) => {
  switch (status) {
    case ProjectStatus.ACTIVE:
      return 'success'
    case 'draft':
      return 'info'
    case 'archived':
      return 'danger'
    default:
      return 'info'
  }
}

// 获取状态名称
const getStatusName = (status: string) => {
  switch (status) {
    case ProjectStatus.ACTIVE:
      return '激活'
    case 'draft':
      return '草稿'
    case 'archived':
      return '归档'
    default:
      return String(status)
  }
}

// 提交表单
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      try {
        // 确保有选定的项目和版本
        if (!selectedProject.value || !selectedProject.value.versions || selectedProject.value.versions.length === 0) {
          ElMessage.error('请选择有效的项目和版本')
          return
        }

        // 从项目版本中获取版本ID
        const selectedVersion = selectedProject.value.versions.find(v => v.version === form.version)
        const versionId = selectedVersion ? selectedVersion.id : null
        
        if (!versionId) {
          ElMessage.error('未找到选择的版本ID，请重新选择')
          return
        }
        
        // 构建部署请求参数
        const deployParams = {
          project_version_id: versionId,
          environment: form.environment,
          deploy_path: form.deploy_path || `/var/www/${selectedProject.value.name}`,
          deployed_by: form.deployed_by || 'admin'
        }
        
        console.log('部署请求参数:', deployParams)
        const response = await createDeployment(deployParams)
        
        // 成功处理
        if (response.code === 0) {
          ElMessage.success('部署创建成功')
          // 跳转到部署详情页面
          if (response.data && typeof response.data === 'object') {
            router.push(`/deploy/detail/${response.data.id || ''}`)
          } else {
            router.push('/deploy/list')
          }
        } else {
          ElMessage.error(response.errorMsg || '部署创建失败')
        }
      } catch (error) {
        console.error('创建部署失败:', error)
        ElMessage.error('创建部署失败')
      }
    } else {
      console.error('表单验证失败:', fields)
    }
  })
}

// 重置表单
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  selectedProject.value = null
}

// 返回
const goBack = () => {
  router.push('/deploy/list')
}

onMounted(() => {
  getProjects()
  fetchServerList()
})
</script>

<style scoped lang="scss">
.deploy-create {
  .el-timeline {
    padding-left: 0;
  }
}
</style>
